package RKUjava.awt.event;
import java.awt.event.*;
import java.awt.Component;

/** The RKUCanvasMouseListener is a kind of MouseListener that can be used in
    connection with Canvas objects. Even though it is used the same
    way a normal eventlistener is it not registered on a canvas the same way
    normal eventlisteners are. It can be used to receive and dispatch events
    on rectangular areas of a canvas. The user is responsible to manage 
    the call to the Dispatcher.<br>
    <b>Note:</b> The different eventlistener methods returns a boolean 
    indicating whether they reacted to the event or not. False means no 
    reaction which causes the event to be passed on to the next listener. 
    (If <tt>consumestrategy</tt> of the dispatcher is 0 or 1)
*/
public class RKUCanvasMouseListener
{
  private int _x1, _y1, _x2, _y2;
  private boolean hasarea;
  private boolean mouseInArea = false;

  /** Create a new PWCanvasMouseListener listening to the rectangle specified 
      by (x1, y1) as upperleft and (x2,y2) as lower right corner.<br>
      initialize(null, null) is called to initialize the listener.
  */
  public RKUCanvasMouseListener(int x1, int y1, int x2, int y2)
  {
    super();
    _x1 = x1; _y1 = y1; _x2 = x2; _y2 = y2;
    hasarea = true;
    initialize(null, null);
    
  }

  /** Create a new PWCanvasMouseListener listening to the rectangle specified 
      by (x1, y1) as upperleft and (x2,y2) as lower right corner. <br>
      initialize(acontainer1, null) is called to initialize the listener.
  */
  public RKUCanvasMouseListener(int x1, int y1, int x2, int y2, Object acontainer1)
  {
    super();
    _x1 = x1; _y1 = y1; _x2 = x2; _y2 = y2;
    hasarea = true;
    initialize(acontainer1, null);
  
  }

  /** Create a new PWCanvasMouseListener listening to the rectangle specified 
      by (x1, y1) as upperleft and (x2,y2) as lower right corner. <br>
      initialize(acontainer1, acontainer2) is called to initialize the listener.
  */
  public RKUCanvasMouseListener(int x1, int y1, int x2, int y2, Object acontainer1, Object acontainer2)
  {
    super();
    _x1 = x1; _y1 = y1; _x2 = x2; _y2 = y2;
    hasarea = true;
    initialize(acontainer1, acontainer2);
  }

  /** Create a new PWCanvasMouseListener listening to the whole area
of the canvas. <br>
      initialize(null, null) is called to initialize the listener.
  */
  public RKUCanvasMouseListener()
  {
    super();
    hasarea = false;
    initialize(null, null);
  }

  /** Create a new PWCanvasMouseListener listening to the whole area
of the canvas. <br>
      initialize(acontainer1, null) is called to initialize the listener.
  */
  public RKUCanvasMouseListener(Object acontainer1)
  {
    super();
    hasarea = false;
    initialize(acontainer1, null);
  
  }

  /** Create a new PWCanvasMouseListener listening to the whole area
of the canvas. <br>
      initialize(acontainer1, acontainer2) is called to initialize the listener.
  */
  public RKUCanvasMouseListener(Object acontainer1, Object acontainer2)
  {
    super();
    hasarea = false;
    initialize(acontainer1, acontainer2);
  }

  /** Called from constructor. Can be used to store the two container objects.
   */
  public void initialize(Object acontainer1, Object acontainer2)
    {
    }

  /** See if this Listener should receive the event and in that case 
      call the right method.
  */
  public boolean dispatchMouseEvent(MouseEvent e)
    {
      int x = e.getX();
      int y = e.getY();

      // Transform MOUSE_MOVED to either MOUSE_ENTERED or MOUSE_EXITED
      if (e.getID()==MouseEvent.MOUSE_MOVED) {
	if (hasarea && (_x1<=x && _y1<=y && x<=_x2 && y<=_y2)) {
	  // Mouse is just moved into the area.
	  if (!mouseInArea) {
	    e = new MouseEvent((Component)e.getSource(), e.MOUSE_ENTERED, e.getWhen(), e.getModifiers(), e.getX(), e.getY(), 0, e.isPopupTrigger());
	    mouseInArea = true;
	  }
	}
	else if (hasarea && !(_x1<=x && _y1<=y && x<=_x2 && y<=_y2)) {
	  // Mouse is just moved out of the area.
	  if (mouseInArea) {
	    e = new MouseEvent((Component)e.getSource(), e.MOUSE_EXITED, e.getWhen(), e.getModifiers(), e.getX(), e.getY(), 0, e.isPopupTrigger());
	    mouseInArea = false;
	  }
	}
      }

      if (!hasarea || (_x1<=x && _y1<=y && x<=_x2 && y<=_y2)) {
	switch(e.getID())
	  {
	  case MouseEvent.MOUSE_CLICKED:
	    return mouseClicked(e);
	  case MouseEvent.MOUSE_ENTERED:
	    return mouseEntered(e);
	  case MouseEvent.MOUSE_EXITED:
	    return mouseExited(e);
	  case MouseEvent.MOUSE_PRESSED:
	    return mousePressed(e);
	  case MouseEvent.MOUSE_RELEASED:
	    return mouseReleased(e);
	  default:
	    return false;
	  }
      } 
      else
	return false;
    }

  
  /** Override this if you want to receive mouse clicks within the rectangle.
      @return true if your overriding methods does something.
  */
  public boolean mouseClicked(MouseEvent e)
    {
      return false;
    }

  /** Override this if you want to receive mouse entered events within the rectangle.
      @return true if your overriding methods does something.
  */
  public boolean mouseEntered(MouseEvent e)
    {
      return false;
    }

  /** Override this if you want to receive mouse exited events within the rectangle.
      @return true if your overriding methods does something.
  */
  public boolean mouseExited(MouseEvent e)
    {
      return false;
    }

  /** Override this if you want to receive mouse pressed events within 
      the rectangle.
      @return true if your overriding methods does something.
  */
  public boolean mousePressed(MouseEvent e)
    {
      return false;
    }

  /** Override this if you want to receive mouse released events within 
      the rectangle.
      @return true if your overriding methods does something.
  */
  public boolean mouseReleased(MouseEvent e)
    {
      return false;
    }
}
